Coretex

您所在的位置:网站首页 stm32h7 cache Coretex

Coretex

2024-07-15 18:47| 来源: 网络整理| 查看: 265

转载自 

STM32H7的Cache和MPU - 灰信网(软件开发博客聚合) (freesion.com)

 

一、Cache

1、介绍

        Cache又分数据缓存D-Cache和指令缓冲I-Cache,STM32H7的数据缓存和指令缓存大小都是16KB。STM32H7主频是400MHz,除了TCM和Cache以400MHz工作,其它AXI SRAM,SRAM1,SRAM2等都是以200MHz工作。数据缓存D-Cache就是解决CPU加速访问SRAM。

        如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。

2、操作,分为读操作和写操作

        读操作: 如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。

       写操作: 如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。

3、H7支持的Cache策略,共4种

4、风险

从上面的图就看出来使用Cache的风险,因为DMA是直接与SRAM交换数据的,而CPU与SRAM之间隔了一个Cache,如果DMA更新了某个数据到SRAM,CPU要去访问,而恰好Cache中有,那么CPU就不会去SRAM中拿,就会拿到Cache中已经过时的数据。因此使用了DMA的内存区要配置为无Cache或者拿数据前清一次Cache。

5、相关函数

SCB_EnableICache :用于使能指令Cache,系统上电后优先初始化即可。

SCB_DisableICache :用于禁止指令Cache。

SCB_InvalidateICache :用于将指令Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的指令。

SCB_EnableDCache :用于使能数据Cache,系统上电后优先初始化即可。

SCB_DisableDCache :用于禁止数据Cache。

SCB_InvalidateDCache :用于将数据Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的数据。

SCB_CleanDCache :用于将数据Cache清除,清除的意思是将Cache Line中标记为dirty的数据写入到相应的存储区。

SCB_CleanInvalidateDCache :此函数是前面两个函数SCB_InvalidateDCache和SCB_CleanDCache的二合一。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。

SCB_InvalidateDCache_by_Addr :可以指定地址和存储区大小。用于将数据Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的数据。

SCB_CleanDCache_by_Addr :可以指定地址和存储区大小。用于将数据Cache清除,清除的意思是将Cache Line中标记为dirty的数据写入到相应的存储区。

SCB_CleanInvalidateDCache_by_Addr:可以指定地址和存储区大小。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。

 

二、MPU

1、作用

        防止不受信任的应用程序访问受保护的内存区域; 防止用户应用程序破坏操作系统使用的数据;通过阻止任务访问其它任务的数据区;允许将内存区域定义为只读,以便保护重要数据;检测意外的内存访问。 简单的说就是内存保护、外设保护和代码访问保护。

2、MPU可以配置的三种内存类型

1)、Normal memory

        CPU以最高效的方式加载和存储字节、半字和字,对于这种内存区,CPU的加载或存储不一定要按照程序列出的顺序执行。 2)、Device memory

        对于这种类型的内存区,加载和存储要严格按照次序进行,这样是为了确保寄存器按照正确顺序设置。

3)、Strongly ordered memory

        程序完全按照代码顺序执行,CPU需要等待当前的加载/存储指令执行完毕后才执行下一条指令。这样会导致性能下降。

3、MPU的使用

        MPU可以配置保护16个内存区域(这16个内存域是独立配置的),每个区域最小要求256字节,每个区域还可以配置为8个子区域。由于子区域一般都相同大小,这样每个子区域的大小就是32字节,正好跟Cache的Cache Line大小一样。

        使用时把一段连续的内存区配置为一个MPU保护区域,然后再配置这个MPU保护区域的特性。比如128KB的DTCM、64KB的SRAM4、32MB的SDRAM。MPU保护区域的特性使用MPU_RASR寄存器来配置,描述如下:

1)、XN:用于控制这个MPU保护区域能否执行程序代码。

2)、AP:用于控制这个MPU保护区域的特权级和非特权级的读写访问权限。

3)、TEX、C、B、S:H7支持4种Cache策略,这几位就是用来控制这个MPU保护区域使用哪一种。

S位用于解决多总线或者多核访问的共享问题,一般不要开启。

4)、SRD:这个位用于控制内存区的子区域 ,使用的是bit[15:8],共计8个bit,一个bit控制一个子区域, 0表示使能此子区域, 1表示禁止。一般情况下,取值0x00,表示8个子区域都使能。

5)、SIZE:配置这个MPU保护区域的大小。

 

三、HAL配置例程 

//设置某个区域的MPU保护 

//baseaddr:MPU保护区域的基址(首地址)

//size:MPU保护区域的大小(必须是32的倍数,单位为字节),可设置的值参考:CORTEX_MPU_Region_Size

//rnum:MPU保护区编号,范围:0~7,最大支持8个保护区域,可设置的值参考:CORTEX_MPU_Region_Number

//ap:访问权限,访问关系如下:可设置的值参考:CORTEX_MPU_Region_Permission_Attributes

//0,无访问(特权&用户都不可访问)

//1,仅支持特权读写访问

//2,禁止用户写访问(特权可读写访问)

//3,全访问(特权&用户都可访问)

//4,无法预测(禁止设置为4!!!)

//5,仅支持特权读访问

//6,只读(特权&用户都不可以写)

//详见:STM32F7 Series Cortex-M7 processor programming manual.pdf,4.6节,Table 89.

//sen:是否允许共用;0,不允许;1,允许

//cen:是否允许catch;0,不允许;1,允许

//返回值;0,成功.

// 其他,错误.

u8 MPU_Set_Protection(u32 baseaddr,u32 size,u32 rnum,u32 ap,u8 sen,u8 cen,u8 ben,u8 Tex)

{

  MPU_Region_InitTypeDef MPU_Initure;

  HAL_MPU_Disable(); //配置MPU之前先关闭MPU,配置完成以后在使能MPU

  MPU_Initure.Enable=MPU_REGION_ENABLE; //使能该保护区域

  MPU_Initure.Number=rnum; //设置保护区域

  MPU_Initure.BaseAddress=baseaddr; //设置基址

  MPU_Initure.Size=size; //设置保护区域大小

  MPU_Initure.SubRegionDisable=0X00; //禁止子区域

  MPU_Initure.TypeExtField=Tex; //设置类型扩展域

  MPU_Initure.AccessPermission=(u8)ap; //设置访问权限,

  MPU_Initure.DisableExec=MPU_INSTRUCTION_ACCESS_ENABLE; //允许指令访问(允许读取指令)

  MPU_Initure.IsShareable=sen; //是否允许共用

  MPU_Initure.IsCacheable=cen; //是否允许cache

  MPU_Initure.IsBufferable=ben; //是否允许缓冲

  HAL_MPU_ConfigRegion(&MPU_Initure); //配置MPU

  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); //开启MPU

  return 0;

}

//设置需要保护的存储块

//必须对部分存储区域进行MPU保护,否则可能导致程序运行异常

//比如MCU屏不显示,摄像头采集数据出错等等问题...

void MPU_Memory_Protection(void) //特意把SRAM4设置为不允许cache,使用DMA的变量可以放在这里。但要注意相应DMA能否访问SRAM4 

{

  MPU_Set_Protection(0x20000000,MPU_REGION_SIZE_128KB,MPU_REGION_NUMBER1,MPU_REGION_FULL_ACCESS,0,1,1,MPU_TEX_LEVEL0); //保护整个DTCM,共128K字节,禁止共用,允许cache,允许缓冲                       

  MPU_Set_Protection(0x24000000,MPU_REGION_SIZE_512KB,MPU_REGION_NUMBER2,MPU_REGION_FULL_ACCESS,0,1,1,MPU_TEX_LEVEL0); //保护整个内部SRAM,包括SRAM1,SRAM2和DTCM,共512K字节                    

  MPU_Set_Protection(0x30000000,MPU_REGION_SIZE_512KB,MPU_REGION_NUMBER3,MPU_REGION_FULL_ACCESS,0,1,1,MPU_TEX_LEVEL0); //保护整个SRAM1~SRAM3,共288K字节,禁止共用,允许cache,允许缓冲  

  MPU_Set_Protection(0x38000000,MPU_REGION_SIZE_64KB ,MPU_REGION_NUMBER4,MPU_REGION_FULL_ACCESS,0,0,1,MPU_TEX_LEVEL0); //保护整个SRAM4,共64K字节,禁止共用,不允许cache,允许缓冲 

  MPU_Set_Protection(0x60000000,MPU_REGION_SIZE_64MB ,MPU_REGION_NUMBER5,MPU_REGION_FULL_ACCESS,0,0,0,MPU_TEX_LEVEL0); //保护MCU LCD屏所在的FMC区域,,共64M字节,禁止共用,禁止cache,禁止缓冲

  MPU_Set_Protection(0xC0000000,MPU_REGION_SIZE_64MB ,MPU_REGION_NUMBER6,MPU_REGION_FULL_ACCESS,0,1,1,MPU_TEX_LEVEL0); //保护SDRAM区域,共32M字节,禁止共用,允许cache,允许缓冲

}

 

 

 

 

 

MPUMPU,即内存保护单元,可以设置不同存储区域的存储器访问特性(如只支持特权访问或全访问)和存储器属性(如可缓存、可缓冲、可共享),对存储器(主要是内存和外设)提供保护,从而提高系统可靠性

通过这些规则可以实现如下功能

防止不受信任的应用程序访问受保护的内存区域。防止用户应用程序破坏操作系统使用的数据。通过阻止任务访问其它任务的数据区。允许将内存区域定义为只读,以便保护重要数据。检测意外的内存访问。也就是内存保护、外设保护和代码访问保护 设置一段内存是只读,还是只允许高权限访问,还是禁止访问等

MPU可以保护的区域为内存映射区 memory map

内存映射区就是 32 位的 CM7 内核整体可以寻址的 0 到 2^32 -1 共计 4GB 的寻址空间。通过这些地址可以访 问 RAM、Flash、外设等。下面是内存映射的轮廓图,IC 厂家使用时,再做细分,添加相应的硬件功能

 

也就是说 MPU可以保护我们的保护内存区域(SRAM 区)不受非法干扰,也可以保护我们的外设区(比如 FMC)

MPU 区域(region)STM32H7 的 MPU 提供多达 16 个可编程保护区域(region)每个区域最小要求 256 字节,序号范围是 0 到 15, 每个区域(region)还可以被进一步划分为更小的子区域(sub region),每个区域(region)都有自己的可编程起始地址、大小及设置。

这些内存区可以嵌套和重叠,所以这些区域在嵌套或者重叠的时候有个优先级的问题。MPU 可以配置的 16 个内存区的序号范围是 0 到 15,序号15 的优先级最高,以此递减,还有默认区 default region,也叫作背景区,序号-1,即背景区的优先级最低。这些优先级是固定的

MPU 功能必须开启才会有效,默认条件下,MPU 是关闭的

MPU在执行其功能时,是以“region区域”为单位的。一个region其实就是一段连续的地址,只是它们的位置和范围都要满足一些限制(对齐方式,最小容量等)

MPU 区域(region)优先级MPU 定义的区域(region)还可以相互交迭。如果某块内存落在多个区域(region)中,则访问属性和权限将由编号最大的 region 来决定。比如,若 3 号 region 与 5 号 region 交迭,则交迭的部分受 5 号 region 控制

比方说5号区域(region)内存是只读模式, 3 号 region内存是读写模式 那么重叠的部分就变成了只读模式,如果对其写入数据则会报错

 

MPU背景区MPU在Region区域之外,还允许启用一个背景区域(即没有MPU 设置的其他所有地址空间),上面图片的空白存储区域。背景区域只允许特权访问。在启用 MPU 后,就不得再访问定义之外的地址区间,也不得访问未经授权的区域(region),否则,将以“访问违例”处理,触发 MemManage 异常

具体的我们在寄存器中讲解,你就会有一个清晰的了解。

MPU 设置是由 CTRL、RNR、RBAR 和 RASR 等寄存器控制的,其中最主要的就是RASR寄存器,下面我们来一一介绍

1.MPU 控制寄存器(CTRL),该寄存器只有最低三位有效

 

PRIVDEFENA 位用于设置是否开启背景区域(region),通过设置该位为 1 即可打开背景区HFNMIENA 位用于控制是否在 NMI 和硬件 faultENABLE 位,则用于控制是否使能 MPU如果PRIVDEFENA 设置为0 那么就只能访问MPU的设置的内存区域,如果访问其他地址就会报错

2.MPU 区域编号寄存器(RNR)

该寄存器只有低 8 位有效 可以读写

在配置一个区域(region)之前,必须先在 MPU 内选中这个区域,我们可以通过将区域编号写入 MPU_RNR 寄存器来完成这个操作。该寄存器只有低 8 位有效,不过由于 STM32H7最多只支持 16 个区域,所以,实际上只有最低 4 位有效(0~15)。在配置完区域编号以后,我们就可以对区域属性进行设置了。

也就是设置要配置那个一内存区域(region)

3. MPU 区域属性和容量寄存器(RASR)

该寄存器是一个32位的寄存器 其中31:29位 27位 23:22位保存,没有作用

XN(28位):用于控制是否允许从此区域提取指令,如果 XN=1,说明禁止从区域提取指令,即这块内存区禁止执行程序代码,如果设置XN=0,则允许提取指令 即这块内存区可以执行程序代码AP 位(bit[26:24]),用于控制Region区域内数据的访问权限(访问许可)三位就对应8中情况具体设置如下:

注意: 下面的TEX,C,B 和 S 都是设置Cache高速缓存的,正常使用MPU是做内存保护,用上面的AP位即可,如果没有用到Cache,下面的配置有个了解即可,在HAL库配置的时候直接禁止,不会有任何影响

TEX,C,B 和 S 的定义如下,这仅关注 TEX = 000 和 001,其它的 TEX 配置基本用不到。

C位:用于使能或者禁止CacheB位:用于配合C位实现Cache下是否使用缓冲S位:用于位用于控制存储器的共享特性,S=1,则二级存储器不可以缓存(Cache),如果设置 S=0,则可以缓存(Cache),一般我们设置该位为 0 即可。按照配置的不同,总共可以分成以下四种:

read/write-through/back/allocate的区别:一、CPU读Cache

Read through:直接从内存区读取数据Read allocate:先把数据读取到Cache中,再从Cache中读取数据二、CPU写Cache若hit命中,有两种处理方式:

Write-through:在数据更新时,把数据同时写入Cache和存储区操作简单,但是写入速度慢Write-back:只有在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。写入速度快,但是一旦更新后的数据未被写入时出现断电,则数据无法找回若miss,有两种处理方式:

Write allocate:先把要写的数据载入到Cache中,写Cache,然后再通过flush的方式写入到内存>中。No-write allocate:并不将写入位置读入缓存,直接把要写的数据写入到内存中。什么叫hit/miss:

一、读操作如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命 中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。二、写操作如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。

SRD位: 用于控制内存区的子区域,一共有8bit,一个bit控制一个子区域,一般都开启RegionSIZE位:配置Region内存区域的大小,最小为32位 可以为32kb 64kb 128kb等等4. MPU 基地址寄存器(RBAR)

ADDR: Region内存区的首地址注意一定要保证首地址跟内存区的大小(RegionSIZE位)对齐,例如,我们定义某个 region 的容量(RegionSIZE位)是 64KB,那么它的基址(ADDR)就必须能被 64KB 整除,也就是这个地址对 64KB,即 0x00010000 求余数等于 0,比如0X0001 0000、0X0002 0000、0X0003 0000 等都可以被整除

VALID 区域编号是否覆盖,如果为1的话将会重新修改ADDR Region内存区的编号REGION 段(bit[3:0]) : 新编号,四位地址对应(0~15)Region内存区的编号在初始化的时候就设置完成,所以一般VALID位设置为0

关于MPU一些基本原理和寄存器就先探讨到这里,下一篇我们来看下HAL库里MPU的配置以及如何使用。

STM32H7内存默认映射和属性

STM32H7 FMC地址

 

 

Cortex-M7内核的Cache是如何提升访问效率的?且看硬核实测-嵌入式系统-与非网 (eefocus.com)

 

 

一、MPU是什么?

MPU 全称"Memory Protection Unit",中文叫“存储保护单元”,它是 Cortex-M 处理器内部的一个模块(注意:并不是所有 Cortex-M 版本都支持 MPU,并且在一些支持 MPU 的 Cortex-M 版本上,MPU 也是可选组件(要看具体MCU厂商是否实现))。

让我们结合如下 Cortex-M 处理器(以 CM0+ 为例,其他版本类似)模块框图中来解释 MPU 作用,从框图中大家可以看到,MPU 介于 Core 和 Bus matrix 中间。Bus matirx 是 ARM 系统总线大管家,用以实现系统内多主(Core,DMA等)、多从(内部RAM,APB外设,外部总线等)的交联和仲裁,Core 通过 Bus matirx 可以访问到系统空间内的所有存储/外设资源,现在 MPU 挡在了 Core 和 Bus matirx 中间,这意味着从此 Core 对系统存储资源的访问需要经过 MPU 的权限控制与审核。

二、存储空间类型与属性

MPU 对存储空间的访问权限控制主要包含:Strongly-ordered(是否严格有序)、Shareable(是否共享)、Cacheable(是否缓存)、Execute Never(是否可执行)等方面,不同的访问权限配置造就了系统里不同的存储空间类型与属性,这一切都是为了能够让存储资源被 Core 高效且可靠地访问(RTOS环境下比裸机程序下更需要可靠保证)。

Shareable/Cacheable/Execute Never 属性大家应该都了解,有必要特别提一下 Strongly-ordered 属性,因为不同属性的存储空间配置会给代码执行时内存访问指令的顺序方面造成了困扰,比如两个内存访问指令A1, A2,假定它们是同一主设备接口发出的,并且 A1 在程序代码里出现在 A2 之前,根据 A1/A2 不同的属性组合其实际执行结果如下,有些时候系统无法保证 A1 操作一定比 A2 操作先完成,这时候需要软件设计里手工插入内存屏障指令(ISB, DSB)来保证最终顺序。

如果 MPU 模块不存在或者没有被使能,处理器系统 4GB 存储空间默认的属性如下(表中 XN 即 Execute Never;WT 即 Write-Throug;WBWA 即 Write-Back, write allocate):

三、MPU功能配置

MPU 模块是处理器内核自带的模块,其寄存器定义见 \CMSIS\Include\core_cm0plus/3/4/7.h 文件,具体寄存器功能解释这里就不展开了,可翻阅对应 ARMv6/7-M Architecture RM 或者 Cortex-M0+/3/4/7 Generic UG 手册找到具体解释。

简单概括一下,MPU 最多支持 8/16 个主空间划分(MPU_RNR[REGION],REGION取值 0-7 或者 0-15),每个主空间可以自由设置其属性(MPU_RASR[XN/AP/TEX/S/C/B]),空间大小是可设的,最小粒度为 32bytes,空间之间也可以重叠(高序号空间属性会覆盖低序号空间属性)。当某个主空间分配的大小超过 256 bytes 时,这个主空间还可以被等分成 8 个子空间,每个子空间有独立的开关控制(MPU_RASR[SRD])。

MPU 模块最核心的寄存器是 MPU_RASR,其提供了存储空间具体访问权限配置,XN/AP/TEX/S/C/B 位域共同决定了最终权限,用户可根据项目实际需求进行配置。

上表中关于 Cache 策略的设置 AA/BB 定义如下: 00 Non-cacheable 01 Write-back, write and read allocate 10 Write-through, no write allocate 11 Write-back, no write allocate

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3